home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power Programmierung
/
Power-Programmierung (Tewi)(1994).iso
/
magazine
/
drdobbs
/
xsharp
/
ball
/
genball.c
< prev
next >
Wrap
Text File
|
1992-03-07
|
6KB
|
197 lines
/* Generates the vertices for a ball approximated with polygonal
facets, in a form suitable for including into a C module. Vertices,
faces, and supporting info is generated, in the following format:
----------------------------start------------------------------
#define NUM_FACES <number of faces in object>
#define NUM_VERTS <number of vertices in object>
Point3 Verts[] = { <vertices in object> };
static int Face0[] = { <vertex indexes for face, clockwise> };
static int Face1[] = { <vertex indexes for face, clockwise> };
:
static int Face<n>[] = { <vertex indexes for face, clockwise> };
static int *VertNumList[] = { <ptr to vertex index list per face> };
static int VertsInFace[] = { <# vertices in each face> };
----------------------------end--------------------------------
*/
#include <stdio.h>
#include <conio.h>
#include <math.h>
#include <string.h>
#include "polygon.h"
#define PI 3.14159265358979323846
#define DOUBLE_TO_FIXED(x) ((long) (x * 65536.0 + 0.5))
void main(void);
void PrintVertex(struct Point3 *);
void Print3Indexes(int, int, int, int);
void Print4Indexes(int, int, int, int, int);
/* Used to rotate around the Y axis by one band's width */
static double YXform[4][4] = {
{1.0, 0.0, 0.0, 0.0},
{0.0, 1.0, 0.0, 0.0},
{0.0, 0.0, 1.0, 0.0},
{0.0, 0.0, 0.0, 1.0}
};
/* Used to rotate around the Z axis by one band's width */
static double ZXform[4][4] = {
{1.0, 0.0, 0.0, 0.0},
{0.0, 1.0, 0.0, 0.0},
{0.0, 0.0, 1.0, 0.0},
{0.0, 0.0, 0.0, 1.0}
};
static FILE *OutputFile; /* where we'll write to */
void main()
{
int Radius, Bands, i, j, LastIndex, BandsX2, LastBandStartIndex;
int TopBandStartIndex, BottomBandStartIndex, FaceNum;
struct Point3 BaseVec, BandVec, WorkingVec, TempVec;
char OutputFilename[130];
char Description[130];
printf("Radius: ");
scanf("%d",&Radius);
printf("Bands: ");
scanf("%d",&Bands);
printf("Output file: ");
OutputFilename[0] = 127;
cgets(OutputFilename);
printf("\nBrief description: ");
Description[0] = 127;
cgets(Description);
printf("\n");
BandsX2 = Bands*2;
if ((OutputFile = fopen(&OutputFilename[2], "w")) == NULL) {
printf("Error\n");
exit(1);
}
/* Descriptive comments */
fprintf(OutputFile, "/* %s */\n", &Description[2]);
fprintf(OutputFile, "/* Created with radius = %d, bands = %d */\n",
Radius, Bands);
/* Defines for # of faces and vertices */
fprintf(OutputFile, "#define NUM_FACES %d\n", BandsX2*Bands);
fprintf(OutputFile, "#define NUM_VERTS %d\n\n",
BandsX2*(Bands-1)+2);
/* Do the vertices */
fprintf(OutputFile, "Point3 Verts[] = {\n");
/* Generate the rotation matrices */
AppendRotationY(YXform, PI / Bands);
AppendRotationZ(ZXform, PI / Bands);
/* Do the point at the top */
BaseVec.X = 0.0;
BaseVec.Y = Radius;
BaseVec.Z = 0.0;
BaseVec.W = 1.0;
PrintVertex(&BaseVec);
BandVec = BaseVec;
/* Do the vertices in each band in turn */
for (i=1; i<Bands; i++) {
/* Rotate around Z to the next band's latitude */
XformVec(ZXform, (double *)&BandVec, (double *)&TempVec);
WorkingVec = BandVec = TempVec;
/* Do the vertices in this band */
for (j=0; j<BandsX2; j++) {
WorkingVec = TempVec;
PrintVertex(&WorkingVec);
/* Now rotate around Y to the next vertex's longitude */
XformVec(YXform, (double *)&WorkingVec, (double *)&TempVec);
}
}
/* Do the point at the bottom */
BaseVec.Y = -Radius;
PrintVertex(&BaseVec);
fprintf(OutputFile, "};\n\n");
/* Do the vertex indexes for each face in each band */
FaceNum = 0;
/* Vertex indexes in top band */
for (i=0; i<BandsX2; i++) {
Print3Indexes(FaceNum++, 0, ((i+1)%BandsX2)+1, i+1);
}
/* Vertex indexes in middle bands */
for (j=0; j<(Bands-2); j++) {
TopBandStartIndex = j*BandsX2 + 1;
BottomBandStartIndex = (j+1)*BandsX2 + 1;
/* Indexes in this band */
for (i=0; i<BandsX2; i++) {
Print4Indexes(FaceNum++, i+TopBandStartIndex,
((i+1)%BandsX2)+TopBandStartIndex,
((i+1)%BandsX2)+BottomBandStartIndex,
i+BottomBandStartIndex);
}
}
/* Vertex indexes in bottom band */
LastIndex = BandsX2*(Bands-1)+1;
LastBandStartIndex = BandsX2*(Bands-2)+1;
for (i=0; i<BandsX2; i++) {
Print3Indexes(FaceNum++, LastBandStartIndex+i,
LastBandStartIndex+((i+1)%BandsX2), LastIndex);
}
/* Do the list of pointers to index arrays for each face */
fprintf(OutputFile, "\nstatic int *VertNumList[] = {\n");
for (i=0; i<(BandsX2*Bands); i++) {
fprintf(OutputFile, "Face%d,\n", i);
}
fprintf(OutputFile, "};\n");
/* Do the # of vertices in each face (3 for the top and bottom
bands, 4 for the rest) */
fprintf(OutputFile, "\nstatic int VertsInFace[] = {\n");
for (i=0; i<BandsX2; i++) fprintf(OutputFile, "3,\n");
for (i=0; i<(BandsX2*(Bands-2)); i++) fprintf(OutputFile, "4,\n");
for (i=0; i<BandsX2; i++) fprintf(OutputFile, "3,\n");
fprintf(OutputFile, "};\n");
exit(0);
}
/* Prints the array of indexes for a 4-vertex face */
void Print4Indexes(int FaceNum, int V1, int V2, int V3, int V4)
{
fprintf(OutputFile, "static int Face%d[] = {%d,%d,%d,%d};\n",
FaceNum, V1, V2, V3, V4);
}
/* Prints the array of indexes for a 3-vertex face */
void Print3Indexes(int FaceNum, int V1, int V2, int V3)
{
fprintf(OutputFile, "static int Face%d[] = {%d,%d,%d};\n",
FaceNum, V1, V2, V3);
}
/* Prints a vertex, in 16.16 fixed-point form */
void PrintVertex(struct Point3 *Vec)
{
long X = DOUBLE_TO_FIXED(Vec->X);
long Y = DOUBLE_TO_FIXED(Vec->Y);
long Z = DOUBLE_TO_FIXED(Vec->Z);
fprintf(OutputFile, "{%ld, %ld, %ld},\n", X, Y, Z);
}